package frame

import (
	"fmt"
	"strings"
	"sync"

	"gitee.com/go-mao/mao/libs/utils"
)

/*
签名中间件
计算规则
sign=SHA256()
*/
func (this *WebEngine) MiddleSign() HandlerFunc {
	var signsMap = new(sync.Map)
	var signLength = 0
	var signKey = strings.TrimSpace(this.server.config.File.Section("server").Key("sign").String())
	return func(w *Webline) {
		if signKey == "" {
			return
		}
		signLength++
		if signLength > 100000 {
			signsMap = new(sync.Map)
			signLength = 0
		}
		signStr := w.GetHeader("Sign")
		if l := len(signStr); l < 74 || l > 104 {
			w.AbortWithStatus(403)
			return
		}
		signIndex := utils.Sha256(w.ClientIP(), w.Request.RequestURI, signStr)
		if _, ok := signsMap.Load(signIndex); ok {
			w.AbortWithStatus(403)
			return
		}
		start := len(signStr) - 64
		token := signStr[:start]
		sign := signStr[start:]
		if utils.Sha256(fmt.Sprint(token, signKey)) != sign { //签名未通过
			w.AbortWithStatus(403)
			return
		}
		signsMap.Store(signIndex, true)
	}
}

/*
限制最大连接数
*/
func (this *WebEngine) middleMaxConnect() HandlerFunc {
	var max = this.server.config.File.Section("server").Key("max_allow").MustInt()
	if max == 0 {
		max = 255
	}
	type s struct{}
	sem := make(chan s, max)
	acquire := func() {
		sem <- s{}
	}
	release := func() {
		<-sem
	}
	return func(c *Webline) {
		acquire()       //before request
		defer release() //after request
		c.Next()
	}
}
